home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / cbzone / cbzone.z / cbzone.tar / c_explode.c < prev    next >
C/C++ Source or Header  |  1991-01-30  |  16KB  |  472 lines

  1. #include "c_includes.h"
  2. /*
  3.  * c_explode.c
  4.  * Todd W Mummert, CMU, January 1991
  5.  *
  6.  * This is an attempt at cleaning up the explosion routines.  Why is this
  7.  * not the same as the drawing routines?  probably should be, but because
  8.  * of the way pieces explode, the equations are more complex.  Rather
  9.  * than slow down the draw routines, we just have a similiar, but
  10.  * different, set of equations here.
  11.  */
  12.  
  13. /*
  14.  * the standard routine for exploding pieces, which will not take
  15.  * into account rotating objects.
  16.  */
  17. void calcpointsV(dc, method, index, g, pl)
  18.      DCp dc;
  19.      Methodp method;
  20.      int index;
  21.      Genericp g, pl;
  22. {
  23.   int i;
  24.   float dx, dy, dz, xn, yn, zn, cn, sn, cp, sp, rx, ry, rz, prx, pry, prz;
  25.   Coord2dp new;
  26.   Coord3dp old;
  27.  
  28.   old = dc->s->object+index;
  29.   new = dc->points+index;
  30.  
  31.   dx = pl->x - g->x - dc->pos.x;
  32.   dy = pl->y - g->y - dc->pos.y;
  33.   dz = - dc->pos.z;
  34.   xn =  dx*dc->cta + dy*dc->sta;
  35.   yn =  -dx*dc->sta*dc->ctp + dy*dc->cta*dc->ctp + dz*dc->stp;
  36.   zn =  dx*dc->sta*dc->stp - dy*dc->cta*dc->stp + dz*dc->ctp;
  37.   cn = pl->ca*dc->cta + pl->sa*dc->sta;
  38.   sn = pl->sa*dc->cta - pl->ca*dc->sta;
  39.   cp = dc->ctp;
  40.   sp = -dc->stp;
  41.   for (i=0; i<method->num; i++, old++, new++) {
  42.     rx =  old->x - xn;
  43.     ry =  old->y - yn;
  44.     rz =  old->z - zn;
  45.     prx =  rx*cn + ry*sn*cp + rz*sn*sp;
  46.     pry = -rx*sn + ry*cn*cp + rz*cn*sp;
  47.     if (pry < 10.0)
  48.       pry = 10.0;
  49.     prz = -ry*sp + rz*cp;
  50.     new->x = 500 + prx / pry * 450;
  51.     new->y = 260 - prz / pry * 450;
  52.   }
  53. }
  54.  
  55. /*
  56.  * the routine that is used for drawing the exploding
  57.  * copter blade.
  58.  */
  59. void calcpointsVI(dc, method, index, g, pl)
  60.      DCp dc;
  61.      Methodp method;
  62.      int index;
  63.      Genericp g, pl;
  64. {
  65.   int i;
  66.   float dx, dy, dz, xn, yn, zn, c1, s1, c2, s2, cp, sp;
  67.   float t1, t2, t3, t4, t5, t6, t7, t8, t9, rx, ry, rz, prx, pry, prz;
  68.   Coord2dp new;
  69.   Coord3dp old;
  70.  
  71.   old = dc->s->object+index;
  72.   new = dc->points+index;
  73.  
  74.   dx = pl->x - g->x - dc->pos.x;
  75.   dy = pl->y - g->y - dc->pos.y;
  76.   dz = - dc->pos.z;
  77.   xn =  dx*dc->cta + dy*dc->sta*dc->ctp + dz*dc->sta*dc->stp;
  78.   yn =  -dx*dc->sta + dy*dc->cta*dc->ctp + dz*dc->cta*dc->stp;
  79.   zn =  -dy*dc->stp + dz*dc->ctp;
  80.   c1 = pl->ca*dc->cta;
  81.   s1 = pl->sa*dc->sta;
  82.   c2 = pl->ca*dc->sta;
  83.   s2 = pl->sa*dc->cta;
  84.   cp = dc->ctp;
  85.   sp = dc->stp;
  86.   t1 = c1 + s1 * cp;
  87.   t2 = -c2 + s2 * cp;
  88.   t3 = -pl->sa * sp;
  89.   t4 = -s2 + c2 * cp;
  90.   t5 = s1 + c1 * cp;
  91.   t6 = -pl->ca * sp;
  92.   t7 = dc->sta * sp;
  93.   t8 = dc->cta * sp;
  94.   t9 = cp;
  95.   for (i=0; i<method->num; i++, old++, new++) {
  96.     rx = old->x - xn;
  97.     ry = old->y - yn;
  98.     rz = old->z - zn;
  99.     prx = rx * t1 + ry * t2 + rz * t3;
  100.     pry = rx * t4 + ry * t5 + rz * t6;
  101.     prz = rx * t7 + ry * t8 + rz * t9;
  102.     if (pry < 10.0)
  103.       pry = 10.0;
  104.     new->x = 500 + prx / pry * 450;
  105.     new->y = 260 - prz / pry * 450;
  106.   }
  107. }
  108.  
  109. void explodeobject(g, pl)
  110.      Genericp g, pl;
  111. {
  112.   static float vars0[] = { 0.996195,  0.087156,  0.996195,  0.087156}; 
  113.   static float vars1[] = { 0.996195, -0.087156,  0.996195, -0.087156}; 
  114.   static float vars2[] = { 0.819152,  0.573576,  0.996195,  0.087156}; 
  115.   static Coord3d tank0[] = {
  116.      30, -53, -15,    35, -60,  15,    35,  60,  -5,    30,  37, -15,
  117.     -30,  37, -15,   -35,  60,  -5,   -35, -60,  15,   -30, -53, -15,
  118.      30, -53, -15,    30,  37, -15,    35, -60,  15,   -35, -60,  15,
  119.      35,  60,  -5,   -35,  60,  -5,   -30, -53, -15,   -30,  37, -15};
  120.   static int tank0pnum[] = {10, 0};
  121.   static int tank0mnum[] = {6, 0};
  122.   static Method tank0methods[] = {16, calcpointsV, NULL,
  123.                                     0, NULL, NULL};
  124.   static Coord3d tank1[] = {
  125.     -10, -50,  10,   -10, -18,  10,    10, -18,  10,    10, -50,  10,
  126.      25, -55, -11,    25,  55, -20,    10, -18,  10,   -10, -18,  10,
  127.     -25,  55, -20,   -25, -55, -11,   -10, -50,  10,    10, -50,  10};
  128.   static int tank1pnum[] = {12, 0};
  129.   static int tank1mnum[] = {0};
  130.   static Method tank1methods[] = {12, calcpointsV, NULL,
  131.                                     0, NULL, NULL};
  132.   static Coord3d tank2[] = {
  133.      -3,  28,  -3,     3,  28,  -3,     3,  28,   3,    -3,  28,   3,
  134.      -3,  28,  -3,     3, -28,   3,     3,  28,   3,    -3, -28,   3,
  135.      -3,  28,   3,    -3, -13,  -3,    -3,  28,  -3,     3, -13,  -3,
  136.       3,  28,  -3};
  137.   static int tank2pnum[] = {5, 0};
  138.   static int tank2mnum[] = {8, 0};
  139.   static Method tank2methods[] = {13, calcpointsV, NULL,
  140.                                     0, NULL, NULL};
  141.   static StaticDC tankstaticdcs[] = {
  142.     tank0, tank0pnum, tank0mnum, tank0methods, COLOR_TANK,
  143.     tank1, tank1pnum, tank1mnum, tank1methods, COLOR_TANK,
  144.     tank2, tank2pnum, tank2mnum, tank2methods, COLOR_TANK};
  145.   static float* tankvars[] = {vars0, vars0, vars1};
  146.   static float tankyoffsets[] = {0.0, 5.0, 32.0};
  147.   static float tankzoffsets[] = {-25.0, 0.0, 0.0};
  148.  
  149.   static Coord3d super0[] = {
  150.      15,  60, -15,    30, -60, -15,    30, -60,  19,    15,  60, -15,
  151.     -15,  60, -15,   -30, -60, -15,   -30, -60,  19,   -15,  60, -15,
  152.     -30, -60,  19,    30, -60,  19,   -30, -60, -15,    30, -60, -15};
  153.   static int super0pnum[] = {8, 0};
  154.   static int super0mnum[] = {4, 0};
  155.   static Method super0methods[] = {12, calcpointsV, NULL,
  156.                                    0, NULL, NULL};
  157.   static Coord3d super1[] = {
  158.       0,  47, -18,    13, -48,   9,    11, -48,  19,    11, -13,  19,
  159.       0,  47, -18,   -13, -48,   9,   -11, -48,  19,   -11, -13,  19,
  160.       0,  47, -18,    11, -48,  19,   -11, -48,  19,    11, -13,  19,
  161.     -11, -13,  19};
  162.   static int super1pnum[] = {9, 0};
  163.   static int super1mnum[] = {4, 0};
  164.   static Method super1methods[] = {13, calcpointsV, NULL,
  165.                                    0, NULL, NULL};
  166.   static Coord3d super2[] = {
  167.       3, -36,   0,     3,  36,   0,    -3, -36,   0,    -3,  36,   0,
  168.       3, -27,  -6,     3,  36,  -6,    -3, -27,  -6,    -3,  36,  -6,
  169.       3,  36,  -6,     3,  36,   0,    -3,  36,   0,    -3,  36,  -6,
  170.       3,  36,  -6};
  171.   static int super2pnum[] = {4, 0};
  172.   static int super2mnum[] = {5, 0};
  173.   static Method super2methods[] = {9, calcpointsV, NULL,
  174.                                    0, NULL, NULL};
  175.  
  176.   static StaticDC superstaticdcs[] = {
  177.     super0, super0pnum, super0mnum, super0methods, COLOR_SUPER,
  178.     super1, super1pnum, super1mnum, super1methods, COLOR_SUPER,
  179.     super2, super2pnum, super2mnum, super2methods, COLOR_SUPER};
  180.   static float superyoffsets[] = {0.0, -12.0, 19.0};
  181.   static float superzoffsets[] = {-25.0, -15.0, 0.0};
  182.  
  183.   static Coord3d missile0[] = {
  184.      15, -30, -25,    25, -30,   0,     0, -45,   0,    15, -30, -25,
  185.     -15, -30, -25,     0, -45,   0,    15, -30,  25,   -15, -30,  25,
  186.       0, -45,   0,   -25, -30,   0,   -15, -30,  25};
  187.   static int missile0pnum[] = {11, 0};
  188.   static int missile0mnum[] = {0};
  189.   static Method missile0methods[] = {11, calcpointsV, NULL,
  190.                                      0, NULL, NULL};
  191.   static Coord3d missile1[] = {
  192.      15, -30, -25,     0,  50,   0,    25, -30,   0,    15, -30,  25,
  193.       0,  50,   0,   -15, -30, -25,   -25, -30,   0,     0,  50,   0,
  194.     -15, -30,  25};
  195.   static int missile1pnum[] = {9, 0};
  196.   static int missile1mnum[] = {0};
  197.   static Method missile1methods[] = {9, calcpointsV, NULL,
  198.                                      0, NULL, NULL};
  199.   static Coord3d missile2[] = {
  200.      13, -17, 11,    15, -30,   5,    23, -38, -10,    23,   0, -10,
  201.      13, -17, 11};
  202.   static int missile2pnum[] = {5, 0};
  203.   static int missile2mnum[] = {0};
  204.   static Method missile2methods[] = {5, calcpointsV, NULL,
  205.                                      0, NULL, NULL};
  206.   static Coord3d missile3[] = {
  207.     -13, -17, 11,   -15, -30,   5,   -23, -38, -10,   -23,   0, -10,
  208.     -13, -17, 11};
  209.   static int missile3pnum[] = {5, 0};
  210.   static int missile3mnum[] = {0};
  211.   static Method missile3methods[] = {5, calcpointsV, NULL,
  212.                                      0, NULL, NULL};
  213.  
  214.   static StaticDC missilestaticdcs[] = {
  215.     missile0, missile0pnum, missile0mnum, missile0methods, COLOR_MISSILE,
  216.     missile1, missile1pnum, missile1mnum, missile1methods, COLOR_MISSILE,
  217.     missile2, missile2pnum, missile2mnum, missile2methods, COLOR_MISSILE,
  218.     missile3, missile3pnum, missile3mnum, missile3methods, COLOR_MISSILE};
  219.   static float* missilevars[] = {vars0, vars0, vars1, vars1};
  220.   static float missileyoffsets[] = {0.0, 0.0, 0.0, 0.0};
  221.   static float missilezoffsets[] = {0.0, 0.0, -30.0, -30.0};
  222.  
  223.   static Coord3d copter0[] = {
  224.       6,  100,   0,     6,  100,   0,    -6, -100,   0,     6, -100,   0,
  225.      -6,  100,   0,     6,  100,   0};
  226.   static int copter0pnum[] = {6, 0};
  227.   static int copter0mnum[] = {0};
  228.   static Method copter0methods[] = {6, calcpointsVI, NULL,
  229.                                     0, NULL, NULL};
  230.   static Coord3d copter1[] = {
  231.       0,  -32, -10,     7,   52, -34,    10,   48, -14,     0,  -34,   0,
  232.       0,  -52,  28,     0,  -62,  28,     0,  -48, -10,     0,  -32, -10,
  233.      -7,   52, -34,   -10,   48, -14,     0,  -34,   0};
  234.   static int copter1pnum[] = {11, 0};
  235.   static int copter1mnum[] = {0};
  236.   static Method copter1methods[] = {11, calcpointsV, NULL,
  237.                                     0, NULL, NULL};
  238.   static Coord3d copter2[] = {
  239.     -14,   34, -34,    14,   34, -34,     0,   60, -14,   -14,   34, -34,
  240.      -7,  -30, -34,     7,  -30, -34,    14,   34, -34,    26,   34, -14,
  241.       0,   60, -14,   -26,   34, -14,   -10,  -34, -14,    10,  -34, -14,
  242.      26,   34, -14,     4,   20,  16,     0,   22,  16,    -4,   20,  16,
  243.      -4,  -22,  16,     4,  -22,  16,     4,   20,  16,   -10,  -34, -14,
  244.      -4,  -22,  16,    10,  -34, -14,     4,  -22,  16,     0,   22,  16,
  245.       0,   60, -14,   -14,   34, -34,   -26,   34, -14,   -26,   34, -14,
  246.      -4,   20,  16};
  247.   static int copter2pnum[] = {19, 0};
  248.   static int copter2mnum[] = {10, 0};
  249.   static Method copter2methods[] = {29, calcpointsV, NULL,
  250.                                     0, NULL, NULL};
  251.   
  252.   static StaticDC copterstaticdcs[] = {
  253.     copter0, copter0pnum, copter0mnum, copter0methods, COLOR_COPTER,
  254.     copter1, copter1pnum, copter1mnum, copter1methods, COLOR_COPTER,
  255.     copter2, copter2pnum, copter2mnum, copter2methods, COLOR_COPTER};
  256.   static float* coptervars[] = {vars2, vars0, vars1};
  257.   static float copteryoffsets[] = {0.0, -82.0, 0.0};
  258.   static float copterzoffsets[] = {30.0, 0.0, 0.0};
  259.  
  260.   static StaticDCp staticdcs[] = {
  261.     NULL, NULL, tankstaticdcs, superstaticdcs,
  262.     missilestaticdcs, copterstaticdcs};
  263.   static float* yoffsets[] = {
  264.     NULL, NULL, tankyoffsets, superyoffsets,
  265.     missileyoffsets, copteryoffsets};
  266.   static float* zoffsets[] = {
  267.     NULL, NULL, tankzoffsets, superzoffsets,
  268.     missilezoffsets, copterzoffsets};
  269.   static float* *vars[] = {
  270.     NULL, NULL, tankvars, tankvars,
  271.     missilevars, coptervars};
  272.   static int pieces[] = {0, 0, 3, 3, 4, 3};
  273.   static float gravity = 1.0;
  274.  
  275.   int color, i, j, p;
  276.   DCp dc;
  277.   Methodp methods;
  278.   float yoffset, dx, dy, temp;
  279.   static int threshold = 0.8;
  280.   Float2d pro;
  281.   float* v;
  282.  
  283.   if (g->type == IS_LANDER) {
  284.     if (g->attr & EXERASE || g->ecount >= 40) {
  285.       g->dc[0].seen = False;
  286.       drawobject(g, pl);
  287.       g->attr = 0;
  288.       return;
  289.     }                                   /* lander just blinks on every */
  290.     if (g->dc[0].seen && g->ccount%3)   /* 3rd cycle                   */
  291.       g->dc[0].seen = False;
  292.     else
  293.       g->ccount = 0;
  294.     drawobject(g, pl);
  295.     g->ccount++;
  296.     return;
  297.   }
  298.  
  299.   p = pieces[g->lntype];
  300.   gprsetdrawvalue(opt->cpi[COLOR_BG]);
  301.   for (i=0; i<p; i++) {
  302.     dc = &g->dc[i];
  303.     if (dc->last) 
  304.       displayobject(dc);
  305.   }
  306.   if (g->attr & EXERASE || g->ecount >= 40) {
  307.     g->attr = 0;
  308.     return;
  309.   }
  310.  
  311.   if (!(g->attr & HAS_DC)) {
  312.     g->attr |= HAS_DC;
  313.     for (i=0; i<p; i++) {
  314.       dc = &g->dc[i];
  315.       dc->s = staticdcs[g->lntype]+i;
  316.  
  317.       switch (g->type) {
  318.       case IS_CUBE:
  319.       case IS_PYRAMID:
  320.       case IS_LANDER:
  321.       case IS_MISSILE:
  322.       case IS_COPTER:
  323.       case IS_SUPER:
  324.       case IS_TANK:
  325.         dc->fades = opt->fading_colors - 1;
  326.         dc->basecolor = dc->s->basecolor;
  327.         break;
  328.       case IS_SALVO:
  329.         dc->fades = False;
  330.         if (g->salvo == pl)
  331.           dc->basecolor = COLOR_PSALVO;
  332.         else
  333.           dc->basecolor = COLOR_ESALVO;
  334.         break;
  335.       }
  336.  
  337.       dc->cta = g->ca;
  338.       dc->sta = g->sa;
  339.       dc->ctp = 1.0;
  340.       dc->stp = 0.0;
  341.       yoffset = *(yoffsets[g->lntype]+i);
  342.       dc->pos.x = -yoffset * g->sa;
  343.       dc->pos.y = yoffset * g->sa;
  344.       dc->pos.z = g->z + *(zoffsets[g->lntype]+i);
  345.       dc->vel.x = frand() * 20.0 - 10.0;
  346.       dc->vel.y = frand() * 20.0 - 10.0;
  347.       dc->vel.z = 12.5 + frand() * 7.5;
  348.     }
  349.     if (g->type == IS_COPTER)
  350.       g->dc[0].vel.z += 6.0;
  351.   }
  352.  
  353.   for (i=0; i<p; i++) {
  354.     dc = &g->dc[i];
  355.     dx = g->x + dc->pos.x - pl->x;
  356.     dy = g->y + dc->pos.y - pl->y;
  357.     if (sqrt(dx*dx + dy*dy) < 2000.0) {
  358.       if (dc->fades) {
  359.         color = g->range/OUT_OF_DRAWING_RANGE * opt->fading_colors;
  360.         if (color >= opt->fading_colors)
  361.           color = opt->fading_colors-1;
  362.       }
  363.       else
  364.         color = 0;
  365.       gprsetdrawvalue(color + opt->cpi[dc->basecolor]);
  366.  
  367.       pro.x = dx * pl->ca + dy * pl->sa;
  368.       pro.y = -dx * pl->sa + dy * pl->ca;
  369.  
  370.       if (pro.y/fabs(pro.x+1) > threshold) {
  371.         methods = dc->s->methods;
  372.         for (j=0; methods->num; methods++) {
  373.           methods->calc(dc, methods, j, g, pl);
  374.           j += methods->num;
  375.         }
  376.         
  377.         displayobject(dc);
  378.         dc->last = True;
  379.       }
  380.       else
  381.         dc->last = False;
  382.     }
  383.     else
  384.         dc->last = False;
  385.  
  386.     dc->pos.x += dc->vel.x;
  387.     dc->pos.y += dc->vel.y;
  388.     dc->vel.z -= gravity;
  389.     dc->pos.z += dc->vel.z;
  390.     if (dc->pos.z < -40.0) {
  391.       dc->pos.z = -40.0;
  392.       dc->vel.z *= -0.2;
  393.     }
  394.  
  395.     v = vars[g->lntype][i];
  396.     temp = dc->cta;
  397.     dc->cta = dc->cta*v[0] - dc->sta*v[1];
  398.     dc->sta = dc->sta*v[0] + temp*v[1];
  399.     temp = dc->ctp;
  400.     dc->ctp = dc->ctp*v[2] - dc->stp*v[3];
  401.     dc->stp = dc->stp*v[2] + temp*v[3];
  402.   }
  403. }
  404.  
  405. void explodesalvo (g, pl)
  406.      Genericp g;
  407.      Genericp pl;
  408. {
  409.   float mrx[5], mry[5];
  410.   float mrz[5], xmoff[5], ymoff[5], zmoff[5];
  411.   static float gravity = 1.0;
  412.   int i, j;
  413.   Coord2dp point, first;
  414.  
  415.   if (g->dc[0].last) {
  416.     gprsetdrawvalue(opt->cpi[COLOR_BG]);
  417.     multiline(g->dc[0].points, 5);
  418.   }
  419.  
  420.   if (g->attr & EXERASE || g->ecount >= 20) {
  421.     g->attr = 0;
  422.     return;
  423.   }
  424.  
  425.   if (g->attr & IS_NEW) {
  426.     g->ccount = 0;
  427.     g->attr &= ~IS_NEW;
  428.     for (j=0; j<5; j++) {
  429.       g->dc[j].vel.x = frand() * 20.0 - 10.0;
  430.       g->dc[j].vel.y = frand() * 20.0 - 10.0;
  431.       g->dc[j].vel.z = -7.5 - frand() * 5.0;
  432.       g->dc[j].pos.x = 0.0;
  433.       g->dc[j].pos.y = 0.0;
  434.       g->dc[j].pos.z = 0.0;
  435.     }
  436.   }
  437.   if (g->dc[0].seen) {
  438.     if (g->salvo == pl)
  439.       gprsetdrawvalue(opt->cpi[COLOR_PSALVO]);
  440.     else
  441.       gprsetdrawvalue(opt->cpi[COLOR_ESALVO]);
  442.     for (i=0; i<5; i++) {
  443.       g->dc[i].pos.x += g->dc[i].vel.x;
  444.       g->dc[i].pos.y += g->dc[i].vel.y;
  445.       g->dc[i].vel.z += gravity;
  446.       g->dc[i].pos.z -= g->dc[i].vel.z;
  447.     }
  448.     point = g->dc[0].points;
  449.     for (i=0; i<5; i++) {
  450.       xmoff[i] = g->dc[i].pos.x + g->x - pl->x;
  451.       ymoff[i] = g->dc[i].pos.y + g->y - pl->y;
  452.       zmoff[i] = g->dc[i].pos.z;
  453.       mrx[i] =  xmoff[i] * pl->ca + ymoff[i] * pl->sa;
  454.       mry[i] = -xmoff[i] * pl->sa + ymoff[i] * pl->ca;
  455.       mrz[i] =  zmoff[i];
  456.       if (mry[i] < 10.0)
  457.         mry[i] = 10.0;
  458.       first = point++;
  459.       point->x = first->x = 500 + mrx[i] / mry[i] * 450;
  460.       first->y = 260 - mrz[i] / mry[i] * 450;
  461.       point->y = first->y+2;
  462.       point++;
  463.     }
  464.     multiline(g->dc[0].points, 5);
  465.     g->dc[0].last = True;
  466.   }
  467.   else
  468.     g->dc[0].last = False;
  469.   g->ccount++;
  470. }
  471.  
  472.